import * as THREE from 'three';
import { Vec3 } from '@/core/types';
import { WorldManager } from '@/world/WorldManager';
import { BlockType } from '@/blocks/types';
import { Player } from '@/player/Player';
import { InputManager } from '@/core/InputManager';
import { TextureManager } from '@/blocks/TextureManager';
import { UI } from '@/ui/UI';
import { InventoryUI } from '@/ui/InventoryUI';
import { CraftingManager } from '@/crafting/CraftingManager';
import { CraftingUI } from '@/ui/CraftingUI';
import { ItemDropManager } from '@/world/ItemDrop';
import { EntityManager } from '@/entities/EntityManager';
import { RedstoneManager } from '@/redstone/RedstoneManager';
import { getAudioManager, AudioManager } from '@/audio/AudioManager';
import { SaveSystem } from '@/world/SaveSystem';
import { WorldSerializer } from '@/world/WorldSerializer';
import { GameModeManager } from '@/core/GameModeManager';
import { GameModeUI } from '@/ui/GameModeUI';
import { DeathUI } from '@/ui/DeathUI';
import { ChatManager } from '@/chat/ChatManager';
import { ChatUI } from '@/chat/ChatUI';
import { AutoChatManager } from '@/chat/AutoChatManager';
import { SpeechBubbleUI } from '@/chat/SpeechBubbleUI';
import { ChatBubbleManager } from '@/chat/ChatBubbleManager';
import { EnhancedInputHandler } from '@/chat/EnhancedInputHandler';
import { Entity } from '@/entities/Entity';

export class Game {
  private canvas: HTMLCanvasElement;
  private scene!: THREE.Scene;
  private camera!: THREE.PerspectiveCamera;
  private renderer!: THREE.WebGLRenderer;
  
  private worldManager!: WorldManager;
  private player!: Player;
  private inputManager!: InputManager;
  private inventoryUI!: InventoryUI;
  private craftingManager!: CraftingManager;
  private craftingUI!: CraftingUI;
  private itemDropManager!: ItemDropManager;
  private entityManager!: EntityManager;
  private redstoneManager!: RedstoneManager;
  private audioManager!: AudioManager;
  private saveSystem!: SaveSystem;
  private worldSerializer!: WorldSerializer;
  private gameModeManager!: GameModeManager;
  private gameModeUI!: GameModeUI;
  private deathUI!: DeathUI;
  private chatManager!: ChatManager;
  private chatUI!: ChatUI;
  private autoChatManager!: AutoChatManager;
  private speechBubbleUI!: SpeechBubbleUI;
  private chatBubbleManager!: ChatBubbleManager;
  private enhancedInputHandler!: EnhancedInputHandler;
  private currentMusicId: string | null = null;
  private musicTimer = 0;
  private musicSwitchInterval = 300; // 5分钟切换音乐
  
  private isRunning = false;

  constructor(canvas: HTMLCanvasElement) {
    this.canvas = canvas;
    
    this.initThreeJS();
    this.initGameSystems().then(() => {
      console.log('Game systems initialized successfully');
    }).catch(error => {
      console.error('Failed to initialize game systems:', error);
    });
  }

  private initThreeJS(): void {
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color(0x87CEEB);
    
    this.camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    
    this.renderer = new THREE.WebGLRenderer({
      canvas: this.canvas,
      antialias: false
    });
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    
    const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
    this.scene.add(ambientLight);
    
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
    directionalLight.position.set(50, 100, 50);
    directionalLight.castShadow = true;
    this.scene.add(directionalLight);
  }

  private async initGameSystems(): Promise<void> {
    // 首先加载材质，确保在创建世界前完成
    console.log('Loading textures...');
    await TextureManager.getInstance().loadTextures();
    console.log('Textures loaded successfully');
    
    this.worldManager = new WorldManager(this.scene);
    this.inputManager = new InputManager(this.canvas);
    this.player = new Player(this.camera, this.inputManager, this.worldManager);
    new UI(this.canvas);
    this.inventoryUI = new InventoryUI(this.player.getInventory());
    
    // 初始化物品掉落系统
    this.itemDropManager = new ItemDropManager(this.scene);
    
    // 初始化实体系统
    this.entityManager = new EntityManager(this.scene, this.worldManager, this.itemDropManager);
    
    // 初始化红石系统
    this.redstoneManager = new RedstoneManager(this.worldManager);
    
    // 初始化音频系统
    this.audioManager = getAudioManager();
    
    // 初始化保存系统
    this.saveSystem = new SaveSystem();
    this.worldSerializer = new WorldSerializer(this.worldManager);
    
    // 初始化合成系统
    this.craftingManager = new CraftingManager();
    this.craftingUI = new CraftingUI(this.craftingManager, this.player.getInventory());
    
    // 初始化游戏模式系统
    this.gameModeManager = new GameModeManager();
    this.gameModeUI = new GameModeUI(this.gameModeManager);
    this.deathUI = new DeathUI(this.gameModeManager);
    
    // 初始化聊天系统
    this.chatManager = new ChatManager();
    this.chatUI = new ChatUI();
    this.autoChatManager = new AutoChatManager();
    this.speechBubbleUI = new SpeechBubbleUI();
    this.chatBubbleManager = new ChatBubbleManager();
    this.enhancedInputHandler = new EnhancedInputHandler(this.inputManager, this.chatUI);
    
    // 设置工作台交互回调
    this.player.setCraftingTableInteractCallback(() => {
      this.craftingUI.toggle();
    });
    
    // 将各种管理器连接到玩家系统
    this.player.setItemDropManager(this.itemDropManager);
    this.player.setRedstoneManager(this.redstoneManager);
    this.player.setInventoryUI(this.inventoryUI);
    this.player.setGameModeManager(this.gameModeManager);
    
    // 设置聊天系统连接
    this.setupChatSystem();
    
    // 设置对话气泡UI的相机
    this.speechBubbleUI.setCamera(this.camera);
    this.chatBubbleManager.setCamera(this.camera);
    this.setupAutoChatSystem();
    
    // 初始化增强输入处理器
    this.enhancedInputHandler.initialize();
    
    // 设置死亡回调
    this.player.setOnDeathCallback((reason: string) => {
      this.deathUI.show(reason);
    });
    
    // 监听重生事件
    document.addEventListener('playerRespawn', (event: any) => {
      this.handlePlayerRespawn(event.detail);
    });
    
    // 加载音频资源
    this.audioManager.loadAudioAssets();
  }

  public start(): void {
    this.isRunning = true;
    this.gameLoop();
  }

  public stop(): void {
    this.isRunning = false;
  }

  private gameLoop(): void {
    if (!this.isRunning) return;
    
    this.update();
    this.render();
    
    requestAnimationFrame(() => this.gameLoop());
  }

  private update(): void {
    // 确保所有系统都已初始化
    if (!this.player || !this.entityManager || !this.worldManager) {
      return;
    }
    
    const deltaTime = 1/60;
    const playerPosition = this.player.getPosition();
    
    // 更新实体系统
    this.entityManager.update(deltaTime, playerPosition);
    
    // 将实体列表传递给玩家用于战斗系统
    this.player.setEntities(this.entityManager.getAllEntities());
    
    this.player.update();
    this.worldManager.update(playerPosition);
    this.inventoryUI.updateHotbar();
    
    // 更新物品掉落系统
    this.itemDropManager.update(deltaTime, playerPosition);
    
    // 更新红石系统
    this.redstoneManager.update(deltaTime);
    
    // 更新音频监听器位置
    this.updateAudioListener();
    
    // 更新背景音乐
    this.updateBackgroundMusic(deltaTime);
    
    // 处理物品收集
    this.handleItemCollection();
    
    // 处理游戏模式UI
    this.handleGameModeUI();
    
    // 更新聊天系统
    this.updateChatSystem();
    
    // 更新对话气泡
    this.speechBubbleUI.update();
    this.chatBubbleManager.update(playerPosition);
    
    // 更新增强输入处理器
    this.enhancedInputHandler.update();
  }

  private updateAudioListener(): void {
    const playerPosition = this.player.getPosition();
    
    // 获取相机的朝向向量
    const forward = new THREE.Vector3();
    this.camera.getWorldDirection(forward);
    
    // 获取相机的上向量
    const up = new THREE.Vector3(0, 1, 0);
    
    // 更新音频监听器位置和朝向
    this.audioManager.updateListenerPosition(
      playerPosition,
      { x: forward.x, y: forward.y, z: forward.z },
      { x: up.x, y: up.y, z: up.z }
    );
  }

  private updateBackgroundMusic(deltaTime: number): void {
    this.musicTimer += deltaTime;
    
    // 如果没有当前音乐或者到了切换时间，选择新音乐
    if (!this.currentMusicId || this.musicTimer >= this.musicSwitchInterval) {
      this.switchBackgroundMusic();
      this.musicTimer = 0;
    }
  }

  private switchBackgroundMusic(): void {
    // 根据游戏模式和时间选择音乐
    const musicTracks = this.getAvailableMusicTracks();
    
    if (musicTracks.length === 0) return;
    
    // 选择一个不同于当前的音乐
    let newMusicId: string;
    do {
      newMusicId = musicTracks[Math.floor(Math.random() * musicTracks.length)];
    } while (newMusicId === this.currentMusicId && musicTracks.length > 1);
    
    // 使用交叉淡入淡出切换音乐
    this.currentMusicId = this.audioManager.crossFadeMusic(newMusicId, true);
    
    if (this.currentMusicId) {
      console.log(`Now playing: ${newMusicId}`);
    }
  }

  private getAvailableMusicTracks(): string[] {
    const gameMode = this.gameModeManager.getCurrentMode();
    const isNightTime = this.isNightTime();
    const playerPosition = this.player.getPosition();
    
    // 基础音乐轨道
    let tracks: string[] = [];
    
    // 根据游戏模式选择音乐
    switch (gameMode) {
      case 'creative':
        tracks = ['music_creative', 'music_peaceful', 'music_ambient'];
        break;
      case 'survival':
        if (isNightTime) {
          tracks = ['music_night', 'music_tense', 'music_mysterious'];
        } else {
          tracks = ['music_calm', 'music_peaceful', 'music_adventure'];
        }
        break;
      case 'hardcore':
        tracks = ['music_tense', 'music_dramatic', 'music_survival'];
        break;
      default:
        tracks = ['music_calm', 'music_peaceful'];
    }
    
    // 根据环境添加特殊音乐
    if (playerPosition.y < 20) {
      // 地下音乐
      tracks.push('music_cave', 'music_underground');
    }
    
    if (playerPosition.y > 80) {
      // 高空音乐
      tracks.push('music_sky', 'music_ethereal');
    }
    
    return tracks;
  }

  private isNightTime(): boolean {
    // 简化的昼夜检测 - 基于游戏时间
    const gameTime = Date.now() / 1000;
    return Math.floor(gameTime / 60) % 2 === 1; // 每分钟切换一次昼夜
  }

  private handleItemCollection(): void {
    const playerPosition = this.player.getPosition();
    const collectableItems = this.itemDropManager.getCollectableItems(playerPosition);
    
    for (const item of collectableItems) {
      // 尝试将物品添加到玩家物品栏
      const success = this.player.getInventory().addItem(item.type, item.count);
      if (success) {
        this.itemDropManager.collectItem(item.id);
      }
    }
  }

  private render(): void {
    this.renderer.render(this.scene, this.camera);
  }

  public async saveWorld(saveId: string): Promise<boolean> {
    try {
      // 序列化世界数据
      const worldData = this.worldSerializer.serializeWorld(this.player, this.entityManager);
      
      // 保存到本地存储
      const success = await this.saveSystem.saveWorld(saveId, worldData);
      
      if (success) {
        console.log(`World saved successfully: ${saveId}`);
      } else {
        console.error(`Failed to save world: ${saveId}`);
      }
      
      return success;
    } catch (error) {
      console.error('Error saving world:', error);
      return false;
    }
  }

  public async loadWorld(saveId: string): Promise<boolean> {
    try {
      // 从本地存储加载世界数据
      const worldData = await this.saveSystem.loadWorld(saveId);
      
      if (!worldData) {
        console.error(`World not found: ${saveId}`);
        return false;
      }
      
      // 反序列化世界数据
      const success = this.worldSerializer.deserializeWorld(worldData, this.player, this.entityManager);
      
      if (success) {
        console.log(`World loaded successfully: ${saveId}`);
      } else {
        console.error(`Failed to load world: ${saveId}`);
      }
      
      return success;
    } catch (error) {
      console.error('Error loading world:', error);
      return false;
    }
  }

  public getSaveSystem(): SaveSystem {
    return this.saveSystem;
  }

  public async clearAllGameData(): Promise<boolean> {
    try {
      // 清除聊天记录
      if (this.chatManager) {
        await this.chatManager.clearAllChatHistory();
      }
      
      // 清除保存的世界数据
      const success = this.saveSystem.clearAllGameData();
      
      if (success) {
        console.log('All game data cleared successfully');
      } else {
        console.error('Failed to clear some game data');
      }
      
      return success;
    } catch (error) {
      console.error('Error clearing game data:', error);
      return false;
    }
  }

  private handleGameModeUI(): void {
    // 检查G键是否被按下来打开游戏模式选择界面
    if (this.inputManager.isKeyPressed('KeyG')) {
      // 使用简单的防抖机制
      const currentTime = Date.now();
      if (!this.lastGKeyTime || currentTime - this.lastGKeyTime > 500) {
        this.gameModeUI.toggle();
        this.lastGKeyTime = currentTime;
      }
    }
  }

  private lastGKeyTime = 0;

  public handleResize(): void {
    this.camera.aspect = window.innerWidth / window.innerHeight;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(window.innerWidth, window.innerHeight);
  }

  public getGameModeManager(): GameModeManager {
    return this.gameModeManager;
  }

  public getGameModeUI(): GameModeUI {
    return this.gameModeUI;
  }

  private handlePlayerRespawn(detail: any): void {
    console.log('Handling player respawn:', detail);
    
    // 重置玩家状态
    this.player.heal(this.player.getMaxHealth()); // 恢复满血
    this.player.addHunger(this.player.getMaxHunger()); // 恢复饥饿值
    
    // 重置玩家位置到出生点
    this.player.setPosition({ x: 0, y: 45, z: 0 });
    
    // 清空玩家的负面状态
    this.player.setFlying(false);
    
    console.log('Player respawned successfully');
  }

  private setupChatSystem(): void {
    // 设置游戏上下文提供者
    this.chatManager.setGameContextProvider((entity: Entity) => {
      return this.getGameContextForChat(entity);
    });

    // 设置自主对话系统
    this.autoChatManager.setGameContextProvider((entity: Entity) => {
      return this.getGameContextForChat(entity);
    });

    // 设置自主对话回调
    this.autoChatManager.setOnAutoChatCallback((entity: Entity, message: string) => {
      this.handleAutoChat(entity, message);
    });

    // 设置聊天UI的消息发送回调
    this.chatUI.onMessageSend(async (message: string) => {
      try {
        await this.chatManager.sendMessage(message);
      } catch (error) {
        console.error('Failed to send chat message:', error);
      }
    });

    // 设置聊天管理器的事件监听
    this.chatManager.addEventListener('message_received', (event: any) => {
      this.chatUI.addMessage(event.data.message);
    });

    this.chatManager.addEventListener('conversation_started', (event: any) => {
      this.chatUI.updateTargetInfo(event.data.entity);
      this.chatUI.show();
    });

    this.chatManager.addEventListener('conversation_ended', () => {
      this.chatUI.updateTargetInfo(null);
      this.chatUI.hide();
    });

    this.chatManager.addEventListener('ai_thinking_start', () => {
      this.chatUI.showTypingIndicator();
    });

    this.chatManager.addEventListener('ai_thinking_end', () => {
      this.chatUI.hideTypingIndicator();
    });

    this.chatManager.addEventListener('target_lost', () => {
      console.log('Chat target lost - too far away');
    });

    this.chatManager.addEventListener('error_occurred', (event: any) => {
      console.error('Chat error:', event.data.error);
    });

    this.chatManager.addEventListener('no_targets_available', (event: any) => {
      console.log(event.data.message);
      // 可以在这里显示UI提示
    });
  }

  private setupAutoChatSystem(): void {
    // 设置游戏上下文提供者
    this.autoChatManager.setGameContextProvider((entity: Entity) => {
      return this.getGameContextForChat(entity);
    });

    // 设置自主对话回调
    this.autoChatManager.setOnAutoChatCallback((entity: Entity, message: string) => {
      this.handleAutoChat(entity, message);
    });

    // 设置检测范围为10格
    this.autoChatManager.setDetectionRange(10);
  }

  private handleAutoChat(entity: Entity, message: string): void {
    console.log(`自主对话触发: ${entity.getType()} 说: "${message}"`);
    
    // 创建自主对话消息
    const chatMessage = {
      id: `auto_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,
      timestamp: Date.now(),
      sender: 'entity' as const,
      content: message,
      entityId: entity.getId(),
      entityType: entity.getType()
    };

    // 显示聊天气泡（这是自主对话的主要显示方式）
    this.chatBubbleManager.showBubble(entity, message);

    // 如果聊天UI当前可见，也在聊天面板中显示消息
    if (this.chatUI.getIsVisible()) {
      this.chatUI.addMessage(chatMessage);
    }

    // 保存到聊天历史
    this.chatManager.getChatStorage().saveMessage(chatMessage);
    
    // 触发自定义事件，其他系统可以监听
    document.dispatchEvent(new CustomEvent('autoChat', {
      detail: { entity, message, chatMessage }
    }));
  }

  private updateChatSystem(): void {
    const playerPosition = this.player.getPosition();
    
    // 检查当前对话目标是否仍在范围内
    this.chatManager.checkTargetInRange(playerPosition);
    
    // 更新自主对话系统
    this.autoChatManager.update(playerPosition, this.entityManager.getAllEntities());
    
    // 处理聊天相关的按键输入
    this.handleChatInput(playerPosition);
  }

  private handleChatInput(playerPosition: Vec3): void {
    // C键切换聊天面板
    if (this.inputManager.isKeyPressed('KeyC')) {
      if (!this.lastCKeyTime || Date.now() - this.lastCKeyTime > 500) {
        if (this.chatManager.getState().isActive) {
          this.chatUI.toggle();
        } else {
          // 使用智能目标选择器找到最佳对话目标
          this.chatManager.selectBestTarget(playerPosition, this.entityManager.getAllEntities());
        }
        this.lastCKeyTime = Date.now();
      }
    }

    // T键选择对话目标（使用智能选择）
    if (this.inputManager.isKeyPressed('KeyT')) {
      if (!this.lastTKeyTime || Date.now() - this.lastTKeyTime > 500) {
        this.chatManager.selectBestTarget(playerPosition, this.entityManager.getAllEntities());
        this.lastTKeyTime = Date.now();
      }
    }
  }



  private calculateDistance(pos1: Vec3, pos2: Vec3): number {
    const dx = pos1.x - pos2.x;
    const dy = pos1.y - pos2.y;
    const dz = pos1.z - pos2.z;
    return Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  private lastCKeyTime = 0;
  private lastTKeyTime = 0;

  public getChatManager(): ChatManager {
    return this.chatManager;
  }

  public getChatUI(): ChatUI {
    return this.chatUI;
  }

  public getAutoChatManager(): AutoChatManager {
    return this.autoChatManager;
  }

  public getChatBubbleManager(): ChatBubbleManager {
    return this.chatBubbleManager;
  }

  public getEnhancedInputHandler(): EnhancedInputHandler {
    return this.enhancedInputHandler;
  }



  private showEntitySpeechBubble(entity: Entity, message: string): void {
    // 使用新的聊天气泡管理器显示气泡
    this.chatBubbleManager.showBubble(entity, message, 4000); // 显示4秒
    console.log(`[${entity.getType()}]: ${message}`);
  }

  private getGameContextForChat(entity: Entity): any {
    const playerPosition = this.player.getPosition();
    const nearbyEntities = this.entityManager.getEntitiesInRange(playerPosition, 10);
    
    // 更详细的时间检测
    const gameTime = Date.now() / 1000;
    const timeOfDay = this.getTimeOfDay(gameTime);
    
    // 获取附近的方块信息
    const nearbyBlocks = this.getNearbyBlocks(playerPosition);
    
    return {
      playerPosition,
      timeOfDay,
      weather: this.getWeather(),
      nearbyBlocks,
      nearbyEntities: nearbyEntities.map(e => e.getType())
    };
  }

  private getTimeOfDay(gameTime: number): 'morning' | 'noon' | 'evening' | 'night' {
    const timePhase = Math.floor(gameTime / 30) % 4; // 每30秒一个时段
    switch (timePhase) {
      case 0: return 'morning';
      case 1: return 'noon';
      case 2: return 'evening';
      case 3: return 'night';
      default: return 'noon';
    }
  }

  private getWeather(): 'clear' | 'rain' | 'storm' {
    // 简化的天气系统 - 基于随机和时间
    const weatherSeed = Math.floor(Date.now() / 60000) % 10; // 每分钟变化
    if (weatherSeed < 7) return 'clear';
    if (weatherSeed < 9) return 'rain';
    return 'storm';
  }

  private getNearbyBlocks(playerPosition: Vec3): BlockType[] {
    const nearbyBlocks: BlockType[] = [];
    const range = 3; // 检测3格范围内的方块
    
    for (let x = -range; x <= range; x++) {
      for (let y = -range; y <= range; y++) {
        for (let z = -range; z <= range; z++) {
          const blockPos = {
            x: Math.floor(playerPosition.x) + x,
            y: Math.floor(playerPosition.y) + y,
            z: Math.floor(playerPosition.z) + z
          };
          
          const blockType = this.worldManager.getBlock(blockPos);
          if (blockType && blockType !== BlockType.AIR) {
            if (!nearbyBlocks.includes(blockType)) {
              nearbyBlocks.push(blockType);
            }
          }
        }
      }
    }
    
    return nearbyBlocks.slice(0, 10); // 限制返回的方块类型数量
  }
}